// 自定协议
#pragma once 

#include <iostream>
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>

using std::string;

 /* #define FLAG 0 */
namespace NS_Protocol
{
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define SEP "\r\n" // 换行
#define SEP_LEN strlen(SEP) 

    class Request // 请求
    {
    public: // 成员变量
        int _result; // 结果
        int _code; // 状态码
        
        int _x; // 值与符号
        int _y;
        char _op;

    public: // 默认成员函数
        Request() {}

        Request(int x, int y, char op): _x(x), _y(y), _op(op)
        {}

        ~Request() {}

    public:
        string Serialize() // 序列化
        {
#ifdef FLAG
            string str; // 存储序列化信息
            str = std::to_string(_x);
            str += SPACE;
            str += _op;
            str += SPACE;
            str += std::to_string(_y);
            str += SEP;

            return str;
#else
            // 创建一个Json::Value对象，用于存储数据
            Json::Value root;
            // 将x值 存储到root对象中
            root["x"] = _x;
            // 将y值 存储到root对象中
            root["y"] = _y;
            // 将操作类型存储到root对象中
            root["op"] = _op;
            // 使用Json::FastWriter对象将root对象转换为字符串
            Json::FastWriter writer; // 将Json数据写入到字符串中
            // 返回root对象转换为字符串的结果
            return writer.write(root);
        // TODO...
#endif
        }


        bool Deserialize(string str) // 反序列化
        {
#ifdef FLAG
            
            std::size_t left = str.find(SPACE);
            if(left == string::npos)
                return false;

            std::size_t right = str.rfind(SPACE);
            if(right == string::npos)
                return false;

            // 获取x y op
            // 获取x
            _x = std::stoi(str.substr(0, left));
            // 获取y
            _y = std::stoi(str.substr(right + SPACE_LEN));

            if(left + SPACE_LEN > str.size())
                return false;
            // 获取op
            _op = str[left + SPACE_LEN];

            return true;
#else
            Json::Value root;
            Json::Reader reader; // 解析Json格式数据
            reader.parse(str, root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
            return true;
#endif
        }

    };
    class Response // 响应
    {
    public: // 成员变量
        int _result; // 结果
        int _code; // 状态码
        
        int _x; // 值与符号
        int _y;
        char _op;

    public: // 默认成员函数
        Response() {}

        Response(int x, int y, char op, int result, int code)
        : _x(x), _y(y), _op(op), _result(result), _code(code)
        {}

        ~Response() {}

    public:
        string Serialize() // 序列化
        {
#ifdef FLAG
            // 计算出的结果信息
            string s; // 存储序列化信息
            s = std::to_string(_code);
            s += SPACE;
            s += std::to_string(_result);

            return s;
#else
            Json::Value root;
            root["code"] = _code;
            root["result"] = _result;
            root["xx"] = _x;
            root["yy"] = _y;
            root["op"] = _op;

            Json::FastWriter writer;
            return writer.write(root);
#endif
        }

        bool Deserialize(const string s)
        {
#ifdef FLAG
            std::size_t pos = s.find(SPACE);
            if(pos = string::npos)
                return false;

            _code = std::stoi(s.substr(0, pos));
            _result = std::stoi(s.substr(pos + SPACE_LEN));
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(s, root); // 解析s到root
            _code = root["code"].asInt();
            _result = root["result"].asInt();
            _x = root["xx"].asInt();
            _y = root["yy"].asInt();
            _op = root["op"].asInt();

            // 判断是否为空
            if(root["xx"].isNull() || root["yy"].isNull() || root["op"].isNull())
                return false;

            return true;
#endif
        }
    };

    bool Recv(int sock, string* out)
    {
        char buffer[1204];
        ssize_t s = recv(sock, buffer, sizeof(buffer), 0); 
        if(s > 0) {
            buffer[s] = '\0';
            *out += buffer;
        } else if (s == 0) {
            std::cout << "client quit." << std::endl;
            return false;
        } else {
            std::cout << "recv error." << std::endl;
            return false;
        }
        return true;
    }

    void Send(int sock, const string& str)
    {
        int n = send(sock, str.c_str(), str.size(), 0);
        
        if(n < 0) {
            std::cout << "send error." << std::endl;
            return;
        }
    }

    string Decode(string& buffer)
    {
        std::size_t pos = buffer.find(SEP);
        if(pos == std::string::npos)
            return "";

        string s = buffer.substr(0, pos);
        buffer = buffer.substr(pos + SEP_LEN);

        return s;
    }

    string Encode(string& s)
    {
        string new_package = std::to_string(s.size());
        new_package += SEP;
        new_package += s;
        new_package += SEP;

        return new_package;
    }

    string Decode(string& buffer) // 拆解获取信息（报文）
    {
        std::size_t pos = buffer.find(SEP);
        if(pos == std::string::npos)
            return "";

        int size = stoi(buffer.substr(0, pos)); // 获取第一段内容
        int surplus = buffer.size() - pos - SEP_LEN * 2; // 剩余的字符数
        if(surplus >= size) {
            buffer.erase(0, pos + SEP_LEN);
            string s = buffer.substr(0, size);
            buffer.erase(0, size + SEP_LEN);
            return s;
        } else {
            return "";
        }

        
    }

    string Encode(string& s) // 添加长度信息，形成完整报文
    {
        string new_package = std::to_string(s.size());
        new_package += SEP;
        new_package += s;
        new_package += SEP;
        return new_package;
    }
}